package com.wf.netty.coder.string;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ReplayingDecoder;

import java.nio.charset.StandardCharsets;
import java.util.List;

/**
 * （1）在协议的Head部分放置字符串的字节长度，可以用一个整数类型来描述。
 * （2）在协议的Content部分，放置字符串的字节数组。
 *
 * step1:解码出字符长度
 * step2：按照第一个阶段的字符串长度解码出字符串的内容
 *
 * @author wf
 * @since 2022/5/26
 */
public class StringReplayDecoder extends ReplayingDecoder<StringReplayDecoder.PHASE> {
    enum PHASE {
        PHASE_1, //第一个阶段：解码出字符串的长度
        PHASE_2  //第二个阶段：按照第一个阶段的字符串长度解码出字符串的内容
    }

    private int length;
    private byte[] inBytes;

    public StringReplayDecoder() {
        //在构造函数中，需要初始化父类的state属性为PHASE_1阶段
        super(PHASE.PHASE_1);
    }

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
        switch (state()) {
            case PHASE_1:
                // step1: 读取字符串长度，创建byte数组
                length = in.readInt();
                inBytes = new byte[length];

                // 进入第二步，读取内容，并设置“读指针检查点”为当前的readerIndex位置
                checkpoint(PHASE.PHASE_2);
                break;
            case PHASE_2:
                // 读取字符串内容
                in.readBytes(inBytes,0, length);
                out.add(new String(inBytes, StandardCharsets.UTF_8));
                // 第二步解析成功，进入下一个字符串解析，并将检查点设置为当前readIndex位置
                checkpoint(PHASE.PHASE_1);
                break;
        }
    }
}
